#include "Account.hh"
#include "Customer.hh"
#include "Utilities.hh"
#include <fstream>
#include <algorithm>
#include "main.hh"


Account::Account(const std::string& id, Customer* holder, double initialBalance, const std::string& type)
    : accountId(id), accountHolder(holder), balance(initialBalance), accountType(type) {
    if (accountHolder) {
        accountHolder->addAccount(this);
    }
}

std::string Account::getAccountId() const {
    return accountId;
}

Customer* Account::getAccountHolder() const {
    return accountHolder;
}

double Account::getBalance() const {
    return balance;
}

const std::vector<Transaction>& Account::getTransactions() const {
    return transactions;
}

std::string Account::getAccountType() const {
    return accountType;
}

void Account::addTransaction(const Transaction& transaction) {
    transactions.push_back(transaction);
}

void Account::addTransaction(double amount, const std::string& type, const std::string& note) {
    Transaction t(amount, type, note);
    transactions.push_back(t);
}

void Account::displayTransactionHistory() const {
    if (transactions.empty()) {
        std::cout << "No transactions found for this account.\n";
        return;
    }

    std::cout << "\n===== Transaction History for Account: " << accountId << " =====\n";
    for (const auto& t : transactions) {
        std::cout << t << "\n";
    }
}

void Account::generateAccountReport(const std::string& filename) const {
    std::ofstream outFile(filename);
    if (!outFile) {
        std::cerr << "Error: Unable to create report file.\n";
        return;
    }

    outFile << "===== Account Report: " << accountId << " =====\n";
    outFile << "Account Holder: " << accountHolder->getName() << "\n";
    outFile << "Account Type: " << accountType << "\n";
    outFile << "Current Balance: " << Utilities::formatCurrency(balance) << "\n\n";
    outFile << "Transaction History:\n";

    for (const auto& t : transactions) {
        outFile << t << "\n";
    }

    outFile.close();
}

std::string Account::generateAccountId(const std::string& accountType) {
    std::string prefix = "62";
    prefix += (accountType == "Savings") ? "21" : "22";
    
    // In a real system, we would check for uniqueness
    // For this example, we'll just generate random numbers
    std::string branchCode = Utilities::generateRandomDigits(4);
    std::string accountNumber = Utilities::generateRandomDigits(8);
    std::string checkDigit = Utilities::generateRandomDigits(4);

    std::string fullId = prefix + "-" + branchCode + "-" + accountNumber.substr(0, 4) + "-" + 
                        accountNumber.substr(4, 4) + "-" + checkDigit;
    
    return fullId;
}